home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TPTUTR~1.ZIP / PASCAL07.TXT < prev    next >
Text File  |  1996-03-21  |  19KB  |  441 lines

  1.                          Turbo Pascal for DOS Tutorial
  2.                               by Glenn Grotzinger
  3.          Part 7 -- Records usage and Mathematics Concepts of Computers
  4.                 All parts copyright 1995 (c) by Glenn Grotzinger
  5.  
  6.         Here is a solution to part 6...
  7.  
  8. {$B+}
  9. program part6;
  10.  
  11.   type
  12.     ltrtype = array['A'..'Z'] of longint; {type dec for arrays}
  13.  
  14.   var
  15.     ltrstorage, sums: ltrtype; { hold array and sums array }
  16.     filelist, counts: text;
  17.     filename: string;
  18.     filenums: integer;
  19.     ltrs: longint;
  20.  
  21.   procedure countletters(str: string; var ltrstorage, sums: ltrtype);
  22.     var
  23.       i: integer; {65..90}
  24.       j: char;
  25.     begin
  26.       for i := 1 to length(str) do  { for length of string }
  27.         for j := 'A' to 'Z' do    { for 26 letters }
  28.           if upcase(str[i]) = j then
  29.             begin
  30.               inc(ltrstorage[j]); {var = var + 1 }
  31.               inc(sums[j]);
  32.               ltrs := ltrs + 1;
  33.             end;
  34.     end;
  35.  
  36.   procedure countfile(filename: string; var ltrstorage:ltrtype; var
  37.                       filenums: integer);
  38.     var
  39.       cntfile: text;
  40.       chkstr: string;
  41.  
  42.     begin
  43.       writeln('Processing ', filename);
  44.       filenums := filenums + 1;
  45.       assign(cntfile, filename);
  46.       reset(cntfile);
  47.       readln(cntfile, chkstr);
  48.       while not eof(cntfile) do
  49.         begin
  50.           countletters(chkstr, ltrstorage, sums);
  51.           readln(cntfile, chkstr);
  52.         end;
  53.       countletters(chkstr, ltrstorage, sums);
  54.       close(cntfile);
  55.     end;
  56.  
  57.   procedure writefdata(filename: string; var ltrstorage: ltrtype);
  58.     var
  59.       i: integer;
  60.       j: char;
  61.     begin
  62.       { write headers }
  63.       writeln(counts, 'Alphabetical Count Data':53);
  64.       writeln(counts, 'for ':40, filename);
  65.       writeln(counts);
  66.       writeln(counts, 'Letter':10, 'Count':10, 'Letter':25, 'Count':10);
  67.       for i := 1 to 13 do
  68.         writeln(counts, chr(i+64):8, ltrstorage[chr(i+64)]:12,
  69.                 chr(i+77):23, ltrstorage[chr(i+77)]:12);
  70.       writeln(counts);
  71.       writeln(counts);
  72.       for j := 'A' to 'Z' do
  73.         ltrstorage[j] := 0; { zero back out storage array }
  74.     end;
  75.  
  76.   procedure doend(filenums: integer; ltrstorage: ltrtype);
  77.     var
  78.       i: integer;
  79.       j: char;
  80.  
  81.     begin
  82.       writeln(counts, filenums, ' files processed.');
  83.       writeln(counts, ltrs, ' letters processed.');
  84.       writeln(counts);
  85.       writeln(counts);
  86.       writefdata('all files', sums);
  87.     end;
  88.  
  89.   begin
  90.     assign(filelist, 'FILES.TXT');
  91.     reset(filelist);
  92.     assign(counts, 'FRNDDATA.TXT');
  93.     rewrite(counts);
  94.     readln(filelist, filename);
  95.     filenums := 0;
  96.     while (not eof(filelist)) and (filenums < 9) do
  97.       begin
  98.         countfile(filename, ltrstorage, filenums);
  99.         writefdata(filename, ltrstorage);
  100.         readln(filelist, filename);
  101.       end;
  102.     countfile(filename, ltrstorage, filenums);
  103.     writefdata(filename, ltrstorage);
  104.     doend(filenums, ltrstorage);
  105.     if not eof(filelist) then
  106.       writeln(counts, 'You gave me more than 10 files to process!');
  107.     close(filelist);
  108.     close(counts);
  109.   end.
  110.  
  111. On with the show....
  112.  
  113. Records Definition
  114. ==================
  115.         You can group up different types of data using records.  We MUST
  116. use the type statement pretty well to use this record type.  Here is an
  117. example of the defining of a record type in the type section.
  118.  
  119.   type
  120.     employeerecord = record
  121.       number: longint;
  122.       surname: string[18];
  123.       firstname: string[10];
  124.       position: string[10];
  125.       yrsworked: integer;
  126.     end;
  127.  
  128. As you can see, we are grouping many different types of information into
  129. one record type.  Then for the var section, all we need to do is define
  130. ONE variable to be of type employeerecord and we'll have the record variable.
  131.  
  132. Accessing Records in a Program
  133. ==============================
  134.         You can work with sections of a record variable, or the whole record
  135. variable.  The whole record variable can be accessed just by calling the
  136. record variable used.  The parts of it require the use of a . followed by
  137. the name of the part as specified in the type statement.  Also, the WITH
  138. command may be used to simplify typing in working with a specific record.
  139. The WITH command specifies a specific record variable to work with.  An
  140. example can be seen below.
  141.  
  142. program tutorial18;
  143.  
  144.   type
  145.     {Employeerecord as above}
  146.   var
  147.     workrecord: employeerecord;
  148.   begin
  149.     { get workrecord into memory here. }
  150.     writeln(workrecord.number);
  151.     writeln(workrecord.surname);
  152.     writeln('I''m getting sick of typing workrecord all the time!');
  153.     with workrecord do
  154.       writeln(firstname);
  155.       writeln(position);
  156.       writeln(yrsworked);
  157.     end;
  158.   end.
  159.  
  160. Hopefully, you can see what exactly is going on in working with records.
  161. WITH only reduces typing.  It's good to use to reduce clutter if you do
  162. a lot with one type of record in a section of code.  Also, keep in mind
  163. that record types can be used in an array....
  164.  
  165.   var
  166.     workinfo: array[1..10] of employeerecord;
  167.  
  168. Each section of the record works just like ordinary variables, and are
  169. addressable like ordinary variables.  Also the whole record itself can
  170. be addressable and moved around (written possibly to binary files?) to
  171. other like records....The above array can be addressed like this:
  172.  
  173. 3rd record in array, surname: workinfo[3].surname
  174.  
  175. Mathematics Concepts in Computers
  176. =================================
  177. Hopefully, you got the mathematics lesson from someone, or are already
  178. familiar with conversion of number bases.  If not, I will run through
  179. a quick example...
  180.  
  181. Convert 10 (base 10) to base 2.
  182.  
  183. A base tells us how many numbers are used in counting.  Typical numerical
  184. usage is base 10 (we use the numbers 0-9 in that order -- we always start
  185. from zero in counting.   To look at this problem, we look at the right
  186. and move to the left with regards to number bases.  To use the example of
  187. 543 in base 10, it's 5X10^2+4X10^1+3X10^0. Remember, anything to the 0th
  188. power is 1. All number bases work this way.  The exception is the changing
  189. of the multiple.  We use 10 in the example above.  Using that background,
  190. 10 in base 10 is 1X10^1+0x10^0.  So, if we go through the process of actually
  191. converting a base from base 10....
  192.  
  193. 10 / 2 = 5 rem 0. (we keep going until the quotient is 0.  Right now it is 5.)
  194. 5 /  2 = 2 rem 1.
  195. 2 / 2 = 1 rem 0.
  196. 1 / 2 = 0 rem 1. (We quit here.  Then look at the remainders from down to
  197.  up to get our converted base).
  198.  
  199. 1010 is 10 in base 2....Now, if we want to go to base 10 from another number.
  200.  
  201. Convert 4A (base 16 to base 10).
  202. Here, since we want to go to base 10, all we need to do is extend out the
  203. base into something we can understand...
  204.  
  205. 4 X 16 + A(10) X 1 = 64 + 10 = 74 (base 10)
  206.  
  207. What does all of this have to do with computers in programming.  Let's
  208. analyze a few things...
  209.  
  210. If you've seen $ and # and what do they mean?
  211. ---------------------------------------------
  212. $ is a typical designator in computers that a number is in base 16. # is
  213. a typical designator in computers that a number is in base 10.  You
  214. probably have seen it by now in the ASCII table studies we have done.
  215. For example, Z is ASCII character $5A and #90.  These are both one in the
  216. same.  As we see below:
  217.  
  218. 5X16^1+A(10)X16^0 = 80 + 10 = 90 (base 10).
  219. 9x10^1+0x10^0 = 5x16^1+10(A)x16^0 (base 16).  {90/16 = 5 rem 10}
  220.  
  221. How does my computer store data?
  222. ================================
  223. Why do we bother to mess with the different number systems in computing?
  224. base 10 is human-understandable, so we use it sometimes.  Base 2 is
  225. obvious, since this is how the computer talks. (hence BI-nary)  All
  226. computer storage is actually a series of 1's and 0's or ON's and OFF's.
  227. (2 possible combinations, hence base 2). For example, lets convert #65 to
  228. base 2 and see how our computers store an A.  Let's start from the highest
  229. we know we can on the power list for 2's. There are 256 ASCII characters
  230. because it was decided sometime in the computer stone age that there would be a
  231. total of 8 bits, the elementary unit of storage in a computer, per byte,
  232. or next major unit that you all should be familar with in using DOS/
  233. Windows/whatever.  If we analyze that using a good permutation scheme..
  234. 2 possible orientations, 8 positions...2^8 or 256 total combinations.
  235. So, we will start from 7, since there is no byte #256.  128 goes into 65
  236. 0 times.  64 goes into 65 one time with 1 left.  32 goes into 1 0 times.
  237. 16 goes into 1 0 times.  8 goes into 1 0 times.  4 goes into 1 0 times.
  238. 2 goes into 1 0 times. 1 goes into 1 one time. (stepping down powers of
  239. 2.). So typically in expressing a list of bits for a byte, we use 0's
  240. for the filler for all 8 spaces, since we NEED to work for 8 bits with
  241. a respective byte.  So an ASCII related system (there are others) would
  242. represent #65 as 0 1 0 0 0 0 0 1.  8 bits, all 0 or 1.  If your computer
  243. deals with an A, it actually deals with the bit series 01000001.
  244.  
  245. In using a computer, we don't need to know about bits, since each
  246. completely meaningful unit to most of us comprises 8 bits.  We don't
  247. need to normally think of 01000001, the way the computer does it.  But
  248. for some things in programming, we do, though.
  249.  
  250. Base 16 is also used a lot.  Reason?  It's a real handy way to define
  251. a byte.  Let's look at the A.  According to the ASCII table, A is $41.
  252. 16 = 2^4 so we can see it's a lot handier way to tag around the implied
  253. bits of a byte with this... If we look at the bit sequence, a high end
  254. of 4 bits would have to be multiplied by 16.  So if we look at the meaning
  255. of 0100 and 0001, we will see why we use base 16... 0100 is 4.  0001 is 1.
  256. Concenate them together, we get 41...Neat, eh?
  257.  
  258. We don't really have all that much concern for base 16 in this tutorial,
  259. because in pascal, base 10 will work as well.  we do need to be concerned
  260. about base 2, though, because the computer uses it.
  261.  
  262. Reasons for knowing what this stuff is...
  263. =========================================
  264. We have reasons that we need to know how to convert between the number
  265. bases, and be familar with what a bit is...You may be familiar with what
  266. is called the high and low orders of a byte.  To use the example of the A
  267. bit series we converted earlier:
  268.  
  269. 0      1      0       0                     0       0       0       1      
  270.       high order                                    low order
  271.  
  272. There are pascal commands which use the bits for things.  Also, some
  273. fixed file formats use these (such as compression -- that's actually whats
  274. going on -- it works at bit level to compress the number of bytes used) and
  275. if you wish to if you ever develop something....)  One must have an idea
  276. of where the bits are coming from, hence all the stuff I was going through
  277. before.  If you read through your TP programmer's reference and see it
  278. talking about orders of bytes and what goes on with those particular
  279. commands, now, you should have the background to know about it and predict
  280. what would happen on those commands.
  281.  
  282. First good commands to know about for working with bits
  283. =======================================================
  284.         We always want to go for the most efficient code available.  If we
  285. ever need to work with multiplying or dividing powers of 2, we can do it
  286. much speedier and easier by having the computer do bit shifts instead of
  287. doing an actual multiply or divide command when we are dealing with small
  288. numbers.  Shifting information around is much easier for the CPU than
  289. actually doing the computation.  Let us demonstrate.
  290.  
  291. 00000010 (base 2) = 2 (base 10)
  292. 00000010 (shift 1 byte to the left) => 00000100 or 4 (base 10)
  293. 00000010 (shift 1 byte to the right) => 00000001 or 1 (base 10)
  294.  
  295. Going one way or the other in shifting bytes have the effect of multiplying
  296. or dividing by 2^(# of bytes we move).  Play with these commands and you
  297. will see.  It's a bit shift that it does, and is MUCH faster than an actual
  298. divide when it comes to any power of 2. Examples:
  299.  
  300. writeln(2 shl 1);   {or 2 X 2^1}
  301. writeln(2 shr 1);   {or 2 / 2^1}
  302.  
  303. Those two commands work this way: <number> command <# of bits to shift>
  304. # of bytes to shift turns out to be the power of 2 we do the work on...
  305.  
  306. HI(byte) pulls the high order of the expression.
  307. LO(byte) pulls the low order of the expression.
  308. swap(byte) swaps the orders.
  309.  
  310. These are all functions.
  311.  
  312. Other Math Functions offered by Pascal
  313. ======================================
  314. Abs(X)          Takes absolute value of X.
  315. Arctan(X)       Takes arctangent of X.
  316. Cos(X)          Takes cosine of X.
  317. Exp(X)          Takes exponential (base e) of argument.
  318. Frac(X)         Returns fraction of X.
  319. Int(X)          Returns integer part of X.
  320. Ln(x)           Takes base e logarithm of X.
  321. Pi              Returns value of pi.
  322. Round(X)        Rounds X(real) to an integer.
  323. sin(X)          Takes sine of X.
  324. sqr(x)          Takes square of X.
  325. sqrt(x)         Takes square root of X.
  326. trunc(x)        Truncates X w/o rounding.
  327.  
  328. It is a good idea to learn basic trigonometry and analytical geometry in
  329. programming.  For example, I know from my studies that Tan(x) would be
  330. 1/Arctan(x) or sin(X) / cos(X).  This stuff is good to know. The reasons?
  331. Graphics.  All one needs to draw anything, really, is a good spot placement
  332. procedure and knowledge of trigonometry, and analytical geometry.  Just
  333. know and define a resolution and then start drawing knowing your knowledge.
  334. As a test, to help out....How would one draw a circle given a central point
  335. and radius?  (Gotoxy in the CRT or WinCRT unit will be of use.  It will
  336. place the cursor at a specified position so you can write something.).
  337. If anyone wants a text-based solution on this one if they can't figure
  338. it out, e-mail ggrotz@2sprint.net.  I will place one in the next part.
  339.  
  340. Other stuff that may prove useful
  341. =================================
  342. In your programming experience, you may have wondered if there is a way
  343. to get a string to an integer, or an integer to a string to do things
  344. with it?  Well, there is.  VAL and STR.
  345.  
  346. Val is used like this:  Val(string, integer, errorinteger);
  347. string is the string you want to try and convert to an integer.
  348. integer is the integer that holds the successful conversion.
  349. errorinteger is <> 0 when there is an error in conversion (always check
  350.    this before you move on after using a VAL!!!
  351.  
  352. Str is used like this: string := str(integer);
  353. string is the string you want to hold the conversion in...
  354. integer is the integer that we want to convert...
  355.  
  356. Another good command to know is POS: integer := pos(substr, str);
  357. It returns 0, if substr isn't there, but it returns a positive value
  358. corresponding to the start of the substring in the string, if it's there.
  359. For example, if we want to find the first use of the word AT in a string...
  360.  
  361. int := pos('AT', 'THAT');
  362.  
  363. int will be 3.
  364.  
  365. Conclusion
  366. ==========
  367. I know all of this mathematics, and talk of bits is probably confusing.
  368. If you don't understand it right now, don't worry about it and go back
  369. at leisure and study it.  It is the basic extent of mathematics behind
  370. the actual operation of a computer and what we all as programmers need
  371. to keep in the back of our minds for some things.  You should know what
  372. a bit is, an order of a byte is, and that there are 8 bits in a byte.
  373. These things should help out in some matters.  You should know the why
  374. parts of these things in some cases...You should especially, though,
  375. understand the parts about the commands SHR, SHL, HI, LO, and SWAP,
  376. and the concepts of orders based on the storage of a byte, as, though
  377. we will not see these in this part, we will undoubtedly see them some-
  378. time before this tutorial is over, more than likely, even we may not
  379. see them.  But you may need to work at bit level with bytes sometime,
  380. so this information is present here now for both the novices and the
  381. experts that may see this.  Also, converting the number bases is a
  382. needed thing.
  383.  
  384. Practice Programming Problem #7
  385. ===============================
  386.         The concept of a record is relatively straight forward.  So I
  387. will not try to come up with a problem for basic usage of records.
  388. But the concept of writing code to do some of the number conversions
  389. is not.  These functions can be very useful for later use in your
  390. programming (save them after you write them!).  Write a function for
  391. your code library that will perform a base 10 to base X number
  392. conversion (X being a variable we can define in the function header to
  393. be an integer.) on an integer.  Also write a function that will perform a
  394. base x to a base 10 conversion.  Inbed these two functions in a program
  395. that will take a number from the keyboard (you can use whatever prompt
  396. you deem to be the least confusing as possible) and a base to convert
  397. the number to.  Put out a prompt as to the answer of what the new base
  398. number of the input is, as well as a restatement of the original number
  399. inputted using a reverse conversion of base (Show us that both of the
  400. functions work and are correct.  If the 2nd computed statement DOES
  401. not equal what is put in, there is an error.), not a direct reprint of
  402. the input variable.  To prove we are not writing out the original input
  403. number that we placed in the keyboard, place a 0 in the keyboard input
  404. variable after you perform the function to convert it to the user's
  405. desired base.
  406.  
  407. Sample Output
  408. -------------
  409. Enter a number: 10
  410. What base do you want to convert it to? 5
  411.  
  412. 10 (base 10) is 20 (base 5).
  413. To check: 20 (base 5) is 10 (base 10).
  414.  
  415. Notes:
  416. 1) You will have to build the converted number base as a string,
  417. because any base beyond 10 requires the use of the alphabet for parts
  418. of the number.
  419. 2) The best way I see to handle the "What do we use for the number
  420. in the result?" question is to define a constant string in the function
  421. to be something like '0123456789ABC...', and address a proper part
  422. of the constant string when we build the converted number for conversion.
  423. 3) Remember we count from x^0 units on the right!!!!!
  424. 4) You will need to probably make the high end limit to be base 36.
  425. 5) Hint: the base x to base 10 function will need to input a string
  426. for the input number and output a longint, while the base 10 to base
  427. x function will need to input a longint and output a string.
  428. 6) A side note for usage.  You can link these two to get from any base
  429. to any base using base 10 as the intermediary.
  430.  
  431. Next Time
  432. =========
  433. We will cover the DOS file function commands out of TP.  Hold on to
  434. your newsreaders because part 8 (right now) is 531 lines, and I'm not
  435. through yet.  This will be one of our special topics.  If you not
  436. familiar with the following concepts in DOS, look up in your DOS
  437. manual and try and pick it up before next time: Read-only file,
  438. hidden file, system file, volume label, command-line parameter, MD,
  439. RD, delete (or erase), the use of * and ? as wildcards.  As always,
  440. any comments, questions, gripes, etc, send them to ggrotz@2sprint.net.
  441.